package com.sihai.ehr.repository;

import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.sihai.ehr.model.biz.*;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.stereotype.Repository;

import com.sihai.core.BaseEntity;
import com.sihai.core.DataAccessor;
import com.sihai.core.QueryCreator;
import com.sihai.ehr.model.sys.AuditStatus;
import com.sihai.ehr.model.sys.Organization;
import com.sihai.ehr.model.sys.OrganizationAuditing;

/**
 * @author: wxn
 * @since: 12-6-24 下午1:05
 *         <p/>
 *         审核仓库类, 供审核相关部分的service调用
 */

@Repository
public class AuditingRepository {
	@Resource
	private DataAccessor dataAccessor;

	private static DecimalFormat df = new DecimalFormat("##.##");

	/**
	 * 查询审核流程记录
	 * 
	 * @param clazz
	 * @param hql
	 * @param args
	 * @param <E>
	 * @return
	 */
	public <E extends AuditingBase> List<List<E>> findByHql(Class<E> clazz,
			String hql, Object[] args) {
		List<E> list = dataAccessor.findByHql(clazz, hql, args, null, null);
		if (list != null && !list.isEmpty()) {
			List<List<E>> audits = new ArrayList<List<E>>();

			// 按审核次号进行分组
			List<E> entity = new ArrayList<E>(); // 一个审核流程
			int auditNo = 1;
			int size = list.size();
			for (int i = 0; i < size; i++) {
				E e = list.get(i);
				if (e.getAuditNo() == auditNo) {
					entity.add(e);
				} else {
					audits.add(entity);
					entity = new ArrayList<E>();
					auditNo = e.getAuditNo();
					entity.add(e);
				}

				if (size - 1 == i) {
					audits.add(entity);
				}
			}

			return audits;
		}

		return null;
	}

	// 创建一个审核流程
	public void saveAuditingProcess(BaseEntity entity, int auditNo) {
		if (entity != null) {
			if (entity instanceof Organization) {
				saveOrganizationAuditingProcess((Organization) entity, auditNo);
			} else if (entity instanceof JobSpecification) {
				saveJobSpecificationAuditingProcess((JobSpecification) entity,
						auditNo);
			} else if (entity instanceof ContractVersion) {
				saveContractVersionAduitingProcess((ContractVersion) entity,
						auditNo);
			} else if (entity instanceof InviteApply) {
				saveInviteApplyAduitingProcess((InviteApply) entity, auditNo);
			} else if (entity instanceof ContractSign
					|| entity instanceof ContractSignZz
					|| entity instanceof ContractSignRt
					|| entity instanceof ContractSignRtt) {
				saveContractSignAduitingProcess(entity, auditNo);
			} else if (entity instanceof Transaction) { // 异动
				saveTransactionProcess((Transaction) entity, auditNo);
			} else if (entity instanceof FinancialReportForm) { // 财务签核系统 -
																// 现金报支单
				saveFinancialReportFormProcess((FinancialReportForm) entity,
						auditNo);
			} else if (entity instanceof FinancialPaymentApplyForm) { // 财务签核系统
																		// -
																		// 用款申请单
				saveFinancialPaymentApplyFormProcess(
						(FinancialPaymentApplyForm) entity, auditNo);
			} else if (entity instanceof FinancialInBillForm) {// 财务签核系统 - 入帐单
				saveFinancialInBillFormProcess((FinancialInBillForm) entity,
						auditNo);
			} else if (entity instanceof AdministrationEvectionApplyForm) {// 行政签核系统
																			// -
																			// 出差申请单
				saveAdministrationEvectionApplyFormProcess(
						(AdministrationEvectionApplyForm) entity, auditNo);
			} else if (entity instanceof AdministrationEvectionReportForm) {// 行政签核系统
																			// -
																			// 出差报告单
				saveAdministrationEvectionReportFormProcess(
						(AdministrationEvectionReportForm) entity, auditNo);
			} else if (entity instanceof AdministrationEvectionCostApplyForm) {// 行政签核系统
																				// -
																				// 出差费用申报单
				saveAdministrationEvectionCostApplyFormProcess(
						(AdministrationEvectionCostApplyForm) entity, auditNo);
			} else if (entity instanceof AdministrationOutApplyForm) {// 行政签核系统
																		// -
																		// 外出申请单
				saveAdministrationOutApplyFormProcess(
						(AdministrationOutApplyForm) entity, auditNo);
			} else if (entity instanceof AdministrationLeaveApplyForm) {// 行政签核系统 - 请假申请单
				saveAdministrationLeaveApplyFormProcess((AdministrationLeaveApplyForm) entity, auditNo);
			} else if (entity instanceof TrainPlan) { // 培训计划审核流程
				if (((TrainPlan) entity).getLecturerType() == 0) { // 内训
					saveTrainPlanAduitingProcess((TrainPlan) entity, auditNo);
				} else { // 外训:创建两个审核流程
					saveTrainPlanAduitingProcess((TrainPlan) entity, auditNo);
					saveTrainOutingPlanCloseAduitingProcess((TrainPlan) entity,
							auditNo);
				}
			} else if (entity instanceof LeaveOfficeApply) {// 离职申请
				saveLeaveOfficeApplyProcess((LeaveOfficeApply) entity, auditNo);
			} else if (entity instanceof ExamQualScore) { // 定性考核
				saveQualScoreTargetAuditingProcess((ExamQualScore) entity,
                        auditNo);
			} else if (entity instanceof ExamAward) {
				saveAwardTargetAuditingProcess((ExamAward) entity, auditNo);
			}
		}
	}

	private void saveQualScoreTargetAuditingProcess(
			final ExamQualScore examQualScore, int auditNo) {
		Organization topOrganization = examQualScore.getEmployeeinfoWork()
				.getOrganization().getTopOrganization() == null ? examQualScore
				.getEmployeeinfoWork().getOrganization() : examQualScore
				.getEmployeeinfoWork().getOrganization().getTopOrganization();
		ExamBaseConfig config = dataAccessor.findUnique(ExamBaseConfig.class,
				new QueryCreator() {

					@Override
					public Query createQuery(Session session) {
						String hql = "from ExamBaseConfig e where e.duty.id=:dutyId";
						Query query = session.createQuery(hql);
						query.setParameter("dutyId", examQualScore
								.getEmployeeinfoWork().getDuty().getId());
						return query;
					}
				});
		if (config != null) {
			List<Auditing> audits = dataAccessor
					.findByHql(
							Auditing.class,
							"from Auditing a where a.auditingNo=? and a.organization=? and a.auditingTargetId=? order by seq asc",
							new Object[] { AuditType.audit_exam_qual_target,
									topOrganization, config.getId() }, null,
							null);
			if (audits != null && !audits.isEmpty()) {
				ExamQualTargetAuditing first = null;
				int size = audits.size();
				for (int i = 0; i < size; i++) {
					Auditing audit = audits.get(i);
					ExamQualTargetAuditing auditing = new ExamQualTargetAuditing();
					auditing.setExamQualScore(examQualScore);
					auditing.setExamBaseConfig(config);
					auditing.setStatus(AuditStatus.wait_audit);
					auditing.setAuditing(audit);
					auditing.setAuditNo(auditNo);
					if (i == size - 1) {
						auditing.setLast(true);
					}
					dataAccessor.save(auditing);
					// if (i == 0) {
					// first = auditing;
					// }
				}
				// 给第一个审核人发消息
				// sendOrganizationMessage(first.getOrganization(),
				// audits.get(0));
			}
		}
	}

	/**
	 * 保存考核审批奖惩流程
	 * 
	 * @param examAward
	 * @param auditNo
	 */
	private void saveAwardTargetAuditingProcess(final ExamAward examAward,
			int auditNo) {
		// 如果是顶级
		Organization topOrganization = examAward.getEmployeeinfoWork()
				.getOrganization().getTopOrganization() == null ? examAward
				.getEmployeeinfoWork().getOrganization() : examAward
				.getEmployeeinfoWork().getOrganization().getTopOrganization();
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { AuditType.audit_exam_award,
								topOrganization }, null, null);
		if (audits != null && !audits.isEmpty()) {
			ExamAwardAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				ExamAwardAuditing auditing = new ExamAwardAuditing();
				auditing.setExamAward(examAward);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核人发消息
			sendAwardMessage(first);
		}
	}

	// 创建一个组织结构审核流程
	private void saveOrganizationAuditingProcess(Organization organization,
			int auditNo) {
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { AuditType.audit_organization,
								organization.getTopOrganization() }, null, null);
		if (audits != null && !audits.isEmpty()) {
			OrganizationAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				OrganizationAuditing auditing = new OrganizationAuditing();
				auditing.setOrganization(organization);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核人发消息
			sendOrganizationMessage(first.getOrganization(), audits.get(0));
		}
	}

	// 创建一个工作说明书审核流程
	private void saveJobSpecificationAuditingProcess(
			JobSpecification jobSpecification, int auditNo) {
		Duty duty = dataAccessor.get(Duty.class, jobSpecification.getDuty()
				.getId());

		// 如果是顶级
		Organization topOrganization = duty.getOrganization()
				.getTopOrganization() == null ? duty.getOrganization() : duty
				.getOrganization().getTopOrganization();
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { AuditType.audit_job_specification,
								topOrganization }, null, null);
		if (audits != null && !audits.isEmpty()) {
			JobSpecificationAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				JobSpecificationAuditing auditing = new JobSpecificationAuditing();
				auditing.setJobSpecification(jobSpecification);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核人发消息
			sendJobSpecificationMessage(first.getJobSpecification(),
					audits.get(0));
		}
	}

	// 创建一个合同版本审核流程
	private void saveContractVersionAduitingProcess(
			ContractVersion contractVersion, int auditNo) {
		// 如果是顶级
		Organization topOrganization = contractVersion.getOrganization()
				.getTopOrganization() == null ? contractVersion
				.getOrganization() : contractVersion.getOrganization()
				.getTopOrganization();
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { AuditType.audit_contract_version,
								topOrganization }, null, null);
		if (audits != null && !audits.isEmpty()) {
			ContractVersionAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				ContractVersionAuditing auditing = new ContractVersionAuditing();
				auditing.setContractVersion(contractVersion);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}

			// 给第一个审核人发消息
			sendContractVersionMessage(first);
		}
	}

	// 创建一个合同签订审核流程
	private void saveContractSignAduitingProcess(BaseEntity contractSign,
			int auditNo) {
		Duty duty = null;
		if (contractSign instanceof ContractSign) {
			duty = ((ContractSign) contractSign).getDuty();
		} else if (contractSign instanceof ContractSignZz) {
			duty = ((ContractSignZz) contractSign).getDuty();
		}else if (contractSign instanceof ContractSignRt) {
			duty = ((ContractSignRt) contractSign).getDuty();
		}else if (contractSign instanceof ContractSignRtt) {
			duty = ((ContractSignRtt) contractSign).getDuty();
		}
		// 如果是顶级
		Organization topOrganization = duty.getOrganization()
				.getTopOrganization() == null ? duty.getOrganization() : duty
				.getOrganization().getTopOrganization();
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { AuditType.audit_contract_sign,
								topOrganization }, null, null);
		if (audits != null && !audits.isEmpty()) {
			ContractSignAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				ContractSignAuditing auditing = new ContractSignAuditing();
				if (contractSign instanceof ContractSign) {
					auditing.setContractSign((ContractSign) contractSign);
				} else if (contractSign instanceof ContractSignZz) {
					auditing.setContractSignZz((ContractSignZz) contractSign);
				}else if (contractSign instanceof ContractSignRt) {
					auditing.setContractSignRt((ContractSignRt) contractSign);
				}else if (contractSign instanceof ContractSignRtt) {
					auditing.setContractSignRtt((ContractSignRtt) contractSign);
				}
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核人发消息
			sendContractSignMessage(first);
		}
	}

	/**
	 * 创建招聘审核流程
	 * 
	 * @param inviteApply
	 * @param auditNo
	 */
	private void saveInviteApplyAduitingProcess(InviteApply inviteApply,
			int auditNo) {
		// 如果是顶级
		Organization topOrganization = inviteApply.getOrganization()
				.getTopOrganization() == null ? inviteApply.getOrganization()
				: inviteApply.getOrganization().getTopOrganization();
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { AuditType.audit_invite_apply,
								topOrganization }, null, null);
		if (audits != null && !audits.isEmpty()) {
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				InviteApplyAuditing auditing = new InviteApplyAuditing();
				auditing.setInviteApply(inviteApply);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
			}
		}
	}

	/**
	 * 创建培训计划审核流程
	 * 
	 * @param trainPlan
	 * @param auditNo
	 */
	public void saveTrainPlanAduitingProcess(TrainPlan trainPlan, int auditNo) {
		// 如果是顶级
		Organization topOrganization = trainPlan.getOrganization()
				.getTopOrganization() == null ? trainPlan.getOrganization()
				: trainPlan.getOrganization().getTopOrganization();
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] {
								trainPlan.getLecturerType() == 0 ? AuditType.audit_train_plan
										: AuditType.audit_train_plan_outing,
								topOrganization }, null, null);
		if (audits != null && !audits.isEmpty()) {
			int size = audits.size();
			TrainPlanAuditing first = null;
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				TrainPlanAuditing auditing = new TrainPlanAuditing();
				auditing.setTrainPlan(trainPlan);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核人发消息
			sendTrainPlanMessage(first);
		}
	}

	/**
	 * 创建培训计划审核流程
	 * 
	 * @param trainPlan
	 * @param auditNo
	 */
	public void saveTrainOutingPlanCloseAduitingProcess(TrainPlan trainPlan,
			int auditNo) {
		// 如果是顶级
		Organization topOrganization = trainPlan.getOrganization()
				.getTopOrganization() == null ? trainPlan.getOrganization()
				: trainPlan.getOrganization().getTopOrganization();
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { AuditType.audit_train_outing_plan_close,
								topOrganization }, null, null);
		if (audits != null && !audits.isEmpty()) {
			int size = audits.size();
			TrainOutingPlanCloseAuditing first = null;
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				TrainOutingPlanCloseAuditing auditing = new TrainOutingPlanCloseAuditing();
				auditing.setTrainPlan(trainPlan);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核人发消息
			sendTrainPlanCloseMessage(first);
		}
	}

	// 创建审核流程
	private void saveTransactionProcess(Transaction entity, int auditNo) {
		AuditType auditType = AuditType.audit_transaction_other;
		if (entity.getType() == Transaction.TransactionType.organization) {
			auditType = AuditType.audit_transaction_organization;
		}
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, entity.getTopOrganization() },
						null, null);
		if (audits != null && !audits.isEmpty()) {
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				TransactionAuditing auditing = new TransactionAuditing();
				auditing.setTransaction(entity);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
			}
		}
	}

	// 创建一个现金报支单审核流程
	private void saveFinancialReportFormProcess(FinancialReportForm form,
			int auditNo) {
		Organization top = (form.getWork().getOrganization()
				.getTopOrganization() == null ? form.getWork()
				.getOrganization() : form.getWork().getOrganization()
				.getTopOrganization());
		AuditType auditType = AuditType.audit_financial_report_form;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, top }, null, null);
		if (audits != null && !audits.isEmpty()) {
			FinancialReportFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				FinancialReportFormAuditing auditing = new FinancialReportFormAuditing();
				auditing.setFinancialReportForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}

			// 给第一个审核结点发消息
			sendFinancialReportFormMessage(first);
		}
	}

	// 创建一个用款申请单审核流程
	private void saveFinancialPaymentApplyFormProcess(
			FinancialPaymentApplyForm form, int auditNo) {
		Organization top = (form.getWork().getOrganization()
				.getTopOrganization() == null ? form.getWork()
				.getOrganization() : form.getWork().getOrganization()
				.getTopOrganization());
		AuditType auditType = AuditType.audit_financial_payment_apply_form;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, top }, null, null);
		if (audits != null && !audits.isEmpty()) {
			FinancialPaymentApplyFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				FinancialPaymentApplyFormAuditing auditing = new FinancialPaymentApplyFormAuditing();
				auditing.setApplyForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}

			// 给第一个审核结点发消息
			sendFinancialPaymentApplyFormMessage(first);
		}
	}

	// 创建一个入帐单审核流程
	private void saveFinancialInBillFormProcess(FinancialInBillForm form,
			int auditNo) {
		Organization top = (form.getWork().getOrganization()
				.getTopOrganization() == null ? form.getWork()
				.getOrganization() : form.getWork().getOrganization()
				.getTopOrganization());
		AuditType auditType = AuditType.audit_financial_in_bill_form;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, top }, null, null);
		if (audits != null && !audits.isEmpty()) {
			FinancialInBillFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				FinancialInBillFormAuditing auditing = new FinancialInBillFormAuditing();
				auditing.setFinancialInBillForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}

			// 给第一个审核结点发消息
			sendFinancialInBillFormMessage(first);
		}
	}

	// 创建一个行政签核系统 - 出差申请单审核流程
	private void saveAdministrationEvectionApplyFormProcess(
			AdministrationEvectionApplyForm form, int auditNo) {
		Organization top = (form.getWork().getOrganization()
				.getTopOrganization() == null ? form.getWork()
				.getOrganization() : form.getWork().getOrganization()
				.getTopOrganization());
		AuditType auditType = AuditType.audit_administration_evection_apply_form;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, top }, null, null);
		if (audits != null && !audits.isEmpty()) {
			AdministrationEvectionApplyFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				AdministrationEvectionApplyFormAuditing auditing = new AdministrationEvectionApplyFormAuditing();
				auditing.setForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}

			// 给第一个审核结点发消息
			sendAdministrationEvectionApplyFormMessage(first);
		}
	}

	// 创建一个行政签核系统 - 出差报告单审核流程
	private void saveAdministrationEvectionReportFormProcess(
			AdministrationEvectionReportForm form, int auditNo) {
		Organization top = (form.getWork().getOrganization()
				.getTopOrganization() == null ? form.getWork()
				.getOrganization() : form.getWork().getOrganization()
				.getTopOrganization());
		AuditType auditType = AuditType.audit_administration_evection_report_form;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, top }, null, null);
		if (audits != null && !audits.isEmpty()) {
			AdministrationEvectionReportFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				AdministrationEvectionReportFormAuditing auditing = new AdministrationEvectionReportFormAuditing();
				auditing.setForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核结点发消息
			sendAdministrationEvectionReportFormMessage(first);
		}
	}

	// 创建一个行政签核系统 - 出差费用申报单审核流程
	private void saveAdministrationEvectionCostApplyFormProcess(
			AdministrationEvectionCostApplyForm form, int auditNo) {
		Organization top = (form.getWork().getOrganization()
				.getTopOrganization() == null ? form.getWork()
				.getOrganization() : form.getWork().getOrganization()
				.getTopOrganization());
		AuditType auditType = AuditType.audit_administration_evection_cost_report_form;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, top }, null, null);
		if (audits != null && !audits.isEmpty()) {
			AdministrationEvectionCostApplyFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				AdministrationEvectionCostApplyFormAuditing auditing = new AdministrationEvectionCostApplyFormAuditing();
				auditing.setForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核结点发消息
			sendAdministrationEvectionCostApplyFormMessage(first);
		}
	}

	// 创建一个行政签核系统 - 外出申请单审核流程
	private void saveAdministrationOutApplyFormProcess(
			AdministrationOutApplyForm form, int auditNo) {
		Organization top = (form.getWork().getOrganization()
				.getTopOrganization() == null ? form.getWork()
				.getOrganization() : form.getWork().getOrganization()
				.getTopOrganization());
		AuditType auditType = AuditType.audit_administration_out_apply_form;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, top }, null, null);
		if (audits != null && !audits.isEmpty()) {
			AdministrationOutApplyFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				AdministrationOutApplyFormAuditing auditing = new AdministrationOutApplyFormAuditing();
				auditing.setForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核结点发消息
			sendAdministrationOutApplyFormMessage(first);
		}
	}

	// 创建一个行政签核系统 - 请假申请单审核流程
	private void saveAdministrationLeaveApplyFormProcess(AdministrationLeaveApplyForm form, int auditNo) {
		Organization top = (form.getWork().getOrganization().getTopOrganization() == null ? form.getWork().getOrganization() : form.getWork().getOrganization().getTopOrganization());
		AuditType auditType = AuditType.audit_administration_leave_apply_form;
		List<Auditing> audits = dataAccessor.findByHql(Auditing.class, "from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc", new Object[]{auditType, top}, null, null);
		if (audits != null && !audits.isEmpty()) {
			AdministrationLeaveApplyFormAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				AdministrationLeaveApplyFormAuditing auditing = new AdministrationLeaveApplyFormAuditing();
				auditing.setForm(form);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}
			// 给第一个审核结点发消息
			sendAdministrationLeaveApplyFormMessage(first);
		}
	}

	// 创建一个离职审核流程
	private void saveLeaveOfficeApplyProcess(LeaveOfficeApply apply, int auditNo) {
		AuditType auditType = AuditType.audit_leave_office;
		List<Auditing> audits = dataAccessor
				.findByHql(
						Auditing.class,
						"from Auditing a where a.auditingNo = ? and a.organization = ? order by a.seq asc",
						new Object[] { auditType, apply.getOrganization() },
						null, null);
		if (audits != null && !audits.isEmpty()) {
			LeaveOfficeApplyAuditing first = null;
			int size = audits.size();
			for (int i = 0; i < size; i++) {
				Auditing audit = audits.get(i);
				LeaveOfficeApplyAuditing auditing = new LeaveOfficeApplyAuditing();
				auditing.setApply(apply);
				auditing.setStatus(AuditStatus.wait_audit);
				auditing.setAuditing(audit);
				auditing.setAuditNo(auditNo);
				if (i == size - 1) {
					auditing.setLast(true);
				}
				dataAccessor.save(auditing);
				if (i == 0) {
					first = auditing;
				}
			}

			// 给第一个审核结点发消息
			sendLeaveOfficeApplyMessage(first);
		}
	}

	// TOTO:删除审核流程
	public void deleteAuditingProcess(BaseEntity entity, String ids) {
		if (entity != null) {
			if (entity instanceof TrainPlan) { // 培训计划审核流程
				deleteTrainPlanAduitingProcess(ids);
				deleteTrainOutingPlanCloseAduitingProcess(ids);
			}
		}
	}

	private void deleteTrainPlanAduitingProcess(final String ids) {
		// delete from TrainPlanAuditing a where a.trainPlan = :trainPlan
		try {
			dataAccessor.batchUpdate(new QueryCreator() {
				@Override
				public Query createQuery(Session session) {
					return session.createQuery(MessageFormat
							.format("delete from TrainPlanAuditing t where t.trainPlan.id in ({0})",
									ids));
				}
			});
		} catch (Exception e) {
			throw new RuntimeException(
					"【异常原因：移出培训计划审核信息数据库发生异常】【异常说明："
							+ e.getMessage()
							+ "】【发生地点：AuditingRepository.deleteTrainPlanAduitingProcess】");
		}
	}

	private void deleteTrainOutingPlanCloseAduitingProcess(final String ids) {
		try {
			dataAccessor.batchUpdate(new QueryCreator() {
				@Override
				public Query createQuery(Session session) {
					return session.createQuery(MessageFormat
							.format("delete from TrainOutingPlanCloseAuditing t where t.trainPlan.id in ({0})",
									ids));
				}
			});
		} catch (Exception e) {
			throw new RuntimeException(
					"【异常原因：移出培训计划审核信息数据库发生异常】【异常说明："
							+ e.getMessage()
							+ "】【发生地点：AuditingRepository.deleteTrainOutingPlanCloseAduitingProcess】");
		}
	}

	// TOTO:创建其他的审核流程

	// 消息相关===============================================================================================
	// 发送一个消息
	public void saveMessage(MessageType type, String targetUrl, Long targetId,
			Duty duty, final EmployeeinfoBase employee, String[] data) {
		if (duty == null && employee == null) {// 没有消息接收者
			return;
		}
		EmployeeinfoWork work = findWork(employee);
		if (duty == null && work == null) {
			return;
		}
		saveMessage(type, targetUrl, targetId, duty, work, data);
	}

	public void saveMessage(MessageType type, String targetUrl, Long targetId,
			Duty duty, final EmployeeinfoWork work, String[] data) {
		try {
			Message message = new Message();
			message.setType(type);
			message.setUnread(true);
			message.setValid(true);
			message.setTargetUrl(targetUrl);
			message.setTargetId(targetId);
			message.setDuty(duty);
			message.setWork(work);
			message.setDateTime(new Date());
			if (data != null && data.length > 0) {
				switch (data.length) {
				case 5:
					message.setData5(data[4]);
				case 4:
					message.setData4(data[3]);
				case 3:
					message.setData3(data[2]);
				case 2:
					message.setData2(data[1]);
				case 1:
					message.setData1(data[0]);
					break;
				}
			}
			dataAccessor.save(message);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void deleteMessage(final MessageType type, final Long targetId) {
		try {
			if (targetId == null) {
				return;
			}
			dataAccessor.batchUpdate(new QueryCreator() {
				@Override
				public Query createQuery(Session session) {
					Query query = session
							.createQuery("delete from Message m where m.type=:mType and m.targetId=:targetId");
					query.setParameter("mType", type);
					query.setParameter("targetId", targetId);
					return query;
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 查找上级部门、上上级部门
	 * 
	 * @param baseDuty
	 *            基节点
	 * @param indicator
	 *            3：则找上级部门， 4：查找上上级部门
	 * @param auditProcess
	 *            配置的审核流程
	 * @param currentAuditNode
	 *            当前审核结点
	 * @return
	 */
	public Duty findUpDuty(Duty baseDuty,
			List<? extends AuditingBase> auditProcess,
			AuditingBase currentAuditNode) {
		try {
			if (auditProcess != null && !auditProcess.isEmpty()) {
				Duty duty = baseDuty;
				for (AuditingBase auditNode : auditProcess) {
					Auditing auditingConfig = auditNode.getAuditing();
					if (auditingConfig.getIndicator() == 3) {// 查找基职务的上级职务
						Duty d = findUpDutyFormJobSpecification(duty);
						if (d == null) {// 没有上级部门，直接返回
							return null;
						}
						// 如果当前查找到当前结点，返回所查找到的上级部门
						if (currentAuditNode.getId().longValue() == auditNode
								.getId().longValue()) {
							return d;
						}
						duty = d;
					} else if (auditingConfig.getIndicator() == 4) { // 查找上上级部门
						Duty d = findUpDutyFormJobSpecification(duty);
						if (d == null) {// 没有上级部门，直接返回
							return null;
						}
						d = findUpDutyFormJobSpecification(d); // 继续查找上级部门的上级部门
						if (d == null) {// 没有上上级部门，直接返回
							return null;
						}
						// 如果当前查找到当前结点，返回所查找到的上级部门
						if (currentAuditNode.getId().longValue() == auditNode
								.getId().longValue()) {
							return d;
						}
						duty = d;
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// 从工作说明书中查找上级部门
	private Duty findUpDutyFormJobSpecification(final Duty duty) {
		if (duty == null) {
			return null;
		}
		try {
			JobSpecification j = dataAccessor.findUnique(
					JobSpecification.class, new QueryCreator() {
						@Override
						public Query createQuery(Session session) {
							Query query = session
									.createQuery("from JobSpecification j where j.duty=:duty");
							query.setParameter("duty", duty);
							return query;
						}
					});

			if (j != null) {
				return j.getPreDuty();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private EmployeeinfoWork findWork(final EmployeeinfoBase employee) {
		if (employee == null || employee.getId() == null) {
			return null;
		}
		try {
			return dataAccessor.findUnique(EmployeeinfoWork.class,
					new QueryCreator() {
						@Override
						public Query createQuery(Session session) {
							Query query = session
									.createQuery("from EmployeeinfoWork w where w.baseId.id=:employeeId");
							query.setParameter("employeeId", employee.getId());
							return query;
						}
					});
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 构建并发送组织架构审核消息(组织架构只能由指定的个人或职务审核)
	 * 
	 * @param organization
	 *            要审核的组织架构
	 * @param auditNode
	 *            审核流程中将要审核的结点
	 */
	public void sendOrganizationMessage(Organization organization,
			Auditing auditNode) {
		if (organization == null || auditNode == null) {
			return;
		}

		try {
			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditNode.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditNode.getEmployee();
			} else if (indicator == 2) {
				duty = auditNode.getDuty();
			}
			String url = String.format(
					"organization/audit_detail.xhtml?organizationId=%s",
					organization.getId().longValue());
			String[] data = { organization.getFullName() };
			saveMessage(MessageType.organization, url, organization.getId(),
					duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 构建并发送工作说明书审核消息(工作说明书只能由指定的个人或职务审核)
	 * 
	 * @param jobSpecification
	 *            要审核的工作说明书
	 * @param auditNode
	 *            审核流程中将要审核的结点
	 */
	public void sendJobSpecificationMessage(JobSpecification jobSpecification,
			Auditing auditNode) {
		if (jobSpecification == null || auditNode == null) {
			return;
		}

		try {
			String displayName = jobSpecification.getDuty().getDutyName();
			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditNode.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditNode.getEmployee();
			} else if (indicator == 2) {
				duty = auditNode.getDuty();
			}
			String url = String
					.format("rank/job_specification_audit_detail.xhtml?jobSpecification.id=%s",
							jobSpecification.getId().longValue());
			String[] data = { displayName };
			saveMessage(MessageType.job_specification, url,
					jobSpecification.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送合同版本审核消息
	public void sendContractVersionMessage(ContractVersionAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			ContractVersion contractVersion = auditNode.getContractVersion();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			}
			String url = String.format(
					"contract/version_audit_detail.xhtml?versionId=%s",
					contractVersion.getId().longValue());
			String[] data = { contractVersion.getContractName(),
					contractVersion.getContractVer() };
			saveMessage(MessageType.contract_version, url,
					contractVersion.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送合同签订审核消息
	public void sendContractSignMessage(ContractSignAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			// ContractSign contractSign = auditNode.getContractSign();
			Auditing auditConfig = auditNode.getAuditing();
			EmployeeinfoWork work = findWork(auditNode.getEmployee());
			if (work == null) {
				return;
			}

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				if (auditNode.getContractSign() != null) {
					List<AuditingBase> auditProcess = dataAccessor
							.findByHql(
									AuditingBase.class,
									"from ContractSignAuditing a where a.auditNo = ? and a.contractSign = ? order by a.id asc",
									new Object[] { auditNode.getAuditNo(),
											auditNode.getContractSign() },
									null, null);
					duty = findUpDuty(work.getDuty(), auditProcess, auditNode);
				} else if (auditNode.getContractSignZz() != null) {
					List<AuditingBase> auditProcess = dataAccessor
							.findByHql(
									AuditingBase.class,
									"from ContractSignAuditing a where a.auditNo = ? and a.contractSignZz = ? order by a.id asc",
									new Object[] { auditNode.getAuditNo(),
											auditNode.getContractSignZz() },
									null, null);
					duty = findUpDuty(work.getDuty(), auditProcess, auditNode);
				}
				//@{ added by henry
				else if (auditNode.getContractSignRt() != null) {
					List<AuditingBase> auditProcess = dataAccessor
							.findByHql(
									AuditingBase.class,
									"from ContractSignAuditing a where a.auditNo = ? and a.contractSignRt = ? order by a.id asc",
									new Object[] { auditNode.getAuditNo(),
											auditNode.getContractSignRt() },
									null, null);
					duty = findUpDuty(work.getDuty(), auditProcess, auditNode);
				}else if (auditNode.getContractSignRtt() != null) {
					List<AuditingBase> auditProcess = dataAccessor
							.findByHql(
									AuditingBase.class,
									"from ContractSignAuditing a where a.auditNo = ? and a.contractSignRtt = ? order by a.id asc",
									new Object[] { auditNode.getAuditNo(),
											auditNode.getContractSignRtt() },
									null, null);
					duty = findUpDuty(work.getDuty(), auditProcess, auditNode);
				}
				
				// @}
			}
			String url = String
					.format("contract/audit_detail.xhtml?signPojo.work.id=%s&signPojo.contractSignId=%s",
							work.getId(), auditNode.getTargetId());
			String[] data = { work.getWorkNo(),
					auditNode.getEmployee().getName() };
			saveMessage(MessageType.contract_sign, url,
					auditNode.getTargetId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送现金报支单审核消息
	public void sendFinancialReportFormMessage(
			FinancialReportFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			FinancialReportForm form = auditNode.getFinancialReportForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from FinancialReportFormAuditing a where a.auditNo = ? and a.financialReportForm = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String
					.format("sign/financial-report-form-audit.xhtml?financialReportForm.id=%s",
							form.getId().longValue());
			String[] data = { form.getSerialNumber(),
					form.getWork().getBaseId().getName(),
					df.format(form.getAmount()) };
			saveMessage(MessageType.financial_report_form, url, form.getId(),
					duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送用款申请单审核消息
	public void sendFinancialPaymentApplyFormMessage(
			FinancialPaymentApplyFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			FinancialPaymentApplyForm form = auditNode.getApplyForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from FinancialPaymentApplyFormAuditing a where a.auditNo = ? and a.applyForm = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String
					.format("sign/financial-payment-apply-form-audit.xhtml?financialPaymentApplyForm.id=%s",
							form.getId().longValue());
			String[] data = { form.getSerialNumber(),
					form.getCompanyFullName(), df.format(form.getAmount()) };
			saveMessage(MessageType.financial_payment_apply_form, url,
					form.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送入帐单审核消息
	public void sendFinancialInBillFormMessage(
			FinancialInBillFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			FinancialInBillForm form = auditNode.getFinancialInBillForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from FinancialInBillFormAuditing a where a.auditNo = ? and a.financialInBillForm = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String
					.format("sign/financial-in-bill-form-audit.xhtml?financialInBillForm.id=%s",
							form.getId().longValue());
			String[] data = { form.getSerialNumber(), form.getType(),
					df.format(form.getAmount()) };
			saveMessage(MessageType.financial_in_bill_form, url, form.getId(),
					duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送出差申请单审核消息
	public void sendAdministrationEvectionApplyFormMessage(
			AdministrationEvectionApplyFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			AdministrationEvectionApplyForm form = auditNode.getForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from AdministrationEvectionApplyFormAuditing a where a.auditNo = ? and a.form = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String
					.format("sign/administration-evection-apply-form-audit.xhtml?applyForm.id=%s",
							form.getId().longValue());
			String[] data = { form.getSerialNumber(),
					form.getWork().getBaseId().getName(),
					form.getEvectionAddress() };
			saveMessage(MessageType.administration_evection_apply_form, url,
					form.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送出差报告单审核消息
	public void sendAdministrationEvectionReportFormMessage(
			AdministrationEvectionReportFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			AdministrationEvectionReportForm form = auditNode.getForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from AdministrationEvectionReportFormAuditing a where a.auditNo = ? and a.form = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String
					.format("sign/administration-evection-report-form-audit.xhtml?reportForm=%s",
							form.getId().longValue());
			String[] data = { form.getSerialNumber(),
					form.getWork().getBaseId().getName() };
			saveMessage(MessageType.administration_evection_report_form, url,
					form.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送出差费用申报单审核消息
	public void sendAdministrationEvectionCostApplyFormMessage(
			AdministrationEvectionCostApplyFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			AdministrationEvectionCostApplyForm form = auditNode.getForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from AdministrationEvectionCostApplyFormAuditing a where a.auditNo = ? and a.form = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String
					.format("sign/administration-evection-cost-apply-form-audit.xhtml?applyForm.id=%s",
							form.getId().longValue());
			String[] data = { form.getSerialNumber(),
					form.getWork().getBaseId().getName(),
					df.format(form.getAmount()) };
			saveMessage(MessageType.administration_evection_cost_report_form,
					url, form.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送外出申报单审核消息
	public void sendAdministrationOutApplyFormMessage(
			AdministrationOutApplyFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			AdministrationOutApplyForm form = auditNode.getForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from AdministrationOutApplyFormAuditing a where a.auditNo = ? and a.form = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String
					.format("sign/administration-out-apply-form-audit.xhtml?applyForm.id=%s",
							form.getId().longValue());
			String[] data = { form.getSerialNumber(),
					form.getWork().getBaseId().getName(),
					form.getEvectionReason(), form.getCustomName() };
			saveMessage(MessageType.administration_out_apply_form, url,
					form.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送请假申报单审核消息
	public void sendAdministrationLeaveApplyFormMessage(AdministrationLeaveApplyFormAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			AdministrationLeaveApplyForm form = auditNode.getForm();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from AdministrationLeaveApplyFormAuditing a where a.auditNo = ? and a.form = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), form },
								null, null);
				duty = findUpDuty(form.getWork().getDuty(), auditProcess, auditNode);
			}
			String url = String.format("sign/administration-leave-apply-form-audit.xhtml?applyForm.id=%s", form.getId().longValue());
			String[] data = { form.getSerialNumber(), form.getWork().getBaseId().getName(), form.getTypeName() };
			saveMessage(MessageType.administration_leave_apply_form, url, form.getId(), duty, employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送离职申请审核消息
	public void sendLeaveOfficeApplyMessage(LeaveOfficeApplyAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			LeaveOfficeApply apply = auditNode.getApply();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from LeaveOfficeApplyAuditing a where a.auditNo = ? and a.apply = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), apply },
								null, null);
				duty = findUpDuty(apply.getWork().getDuty(), auditProcess,
						auditNode);
			}
			String url = String.format("leave/apply-audit.xhtml?apply.id=%s",
					apply.getId().longValue());
			String[] data = { apply.getWork().getWorkNo(),
					apply.getWork().getBaseId().getName() };
			saveMessage(MessageType.leave_office, url, apply.getId(), duty,
					employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送培训结案审核消息
	public void sendQualScoreMessage(ExamQualTargetAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			ExamQualScore score = auditNode.getExamQualScore();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from ExamQualTargetAuditing a where a.auditNo = ? and a.examQualScore = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), score },
								null, null);
				duty = findUpDuty(score.getEmployeeinfoWork().getDuty(),
						auditProcess, auditNode);
			}
			// #exam/qual_score_dist_detail.xhtml?op=fr&type=${type}&periodDesc=${periodDesc}&workId=${qualscore.workId}
			String url = String
					.format("exam/qual_score_dist_detail.xhtml?op=fr&type=%s&periodDesc=%s&workId=%s",
							score.getExamPeriod().getPeriodType().toString(),
							score.getExamPeriod().getExamYear() + "-"
									+ score.getExamPeriod().getExamMonthly(),
							score.getEmployeeinfoWork().getId());
			String[] data = { score.getExamPeriod().getPeriodName(),
					score.getEmployeeinfoWork().getDuty().getDutyName() };
			saveMessage(MessageType.exam_qual_target, url, score.getId(), duty,
					employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送培训计划审核消息
	public void sendTrainPlanMessage(TrainPlanAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			TrainPlan plan = auditNode.getTrainPlan();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from TrainPlanAuditing a where a.auditNo = ? and a.trainPlan = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), plan },
								null, null);
				duty = findUpDuty(plan.getDuty(), auditProcess, auditNode);
			}
			String url = String.format("train/plan_audit.xhtml?planId=%s", plan
					.getId().longValue());
			if (plan.getLecturerType() > 0) {
				url = String.format("train/outing_train_audit.xhtml?planId=%s",
						plan.getId().longValue());
			}
			String[] data = { plan.getTitle(),
					plan.getDuty() == null ? "" : plan.getDuty().getDutyName() };
			saveMessage(MessageType.train_plan, url, plan.getId(), duty,
					employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 发送培训结案审核消息
	public void sendTrainPlanCloseMessage(TrainOutingPlanCloseAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			TrainPlan plan = auditNode.getTrainPlan();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from TrainOutingPlanCloseAuditing a where a.auditNo = ? and a.trainPlan = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(), plan },
								null, null);
				duty = findUpDuty(plan.getDuty(), auditProcess, auditNode);
			}
			String url = String.format(
					"train/outing_close_audit_main.xhtml?planId=%s", plan
							.getId().longValue());
			String[] data = { plan.getTitle(),
					plan.getDuty() == null ? "" : plan.getDuty().getDutyName() };
			saveMessage(MessageType.train_plan_close, url, plan.getId(), duty,
					employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void sendAwardMessage(ExamAwardAuditing auditNode) {
		if (auditNode == null) {
			return;
		}
		try {
			ExamAward examAward = auditNode.getExamAward();
			Auditing auditConfig = auditNode.getAuditing();

			Duty duty = null;
			EmployeeinfoBase employee = null;
			int indicator = auditConfig.getIndicator();
			// 1-指定人审核（employee）, 2-指定职务审核（duty,） 3-上级领导审核, 4-上上级领导审核
			if (indicator == 1) {
				employee = auditConfig.getEmployee();
			} else if (indicator == 2) {
				duty = auditConfig.getDuty();
			} else if (indicator == 3 || indicator == 4) {
				List<AuditingBase> auditProcess = dataAccessor
						.findByHql(
								AuditingBase.class,
								"from ExamAwardAuditing a where a.auditNo = ? and a.examAward = ? order by a.id asc",
								new Object[] { auditNode.getAuditNo(),
										examAward }, null, null);
				duty = findUpDuty(examAward.getEmployeeinfoWork().getDuty(),
						auditProcess, auditNode);
			}
			String url = String.format(
					"exam/award_audit_detail.xhtml?examAward.id=%s", examAward
							.getId().longValue());
			String[] data = {
					examAward.getExamAwardItem().getTitle(),
					examAward.getEmployeeinfoWork().getDuty() == null ? ""
							: examAward.getEmployeeinfoWork().getDuty()
									.getDutyName() };
			saveMessage(MessageType.exam_award, url, examAward.getId(), duty,
					employee, data);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
